{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to Jupyter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What are Jupyter notebooks? This is a critical one to start with so you've got a good idea of what they are! So following along with the next few notebooks before you do anything else!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Running Tutorials"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Jupyter notebooks are documents that combine Python code, rich text, and additional code (such as Bash), organized into executable blocks. Notebooks allow users to run blocks out of order and multiple times, giving greater control over what's being run than a Python script. To run these notebooks, you'll need to install the Jupyter Notebook application (see [Installing ChipWhisperer](https://chipwhisperer.readthedocs.io/en/latest/installation.html)), which also includes file browser and text editor capabilities.\n",
    "\n",
    "Below is an example of a Python block. First select the block by clicking on it. A green or blue border should appear around the block, indicating that the block is selected. Next, hit the `>| Run` button on the toolbar at the top of your screen. The next block should now be highlighted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "State is kept between Python blocks. Try running the next block multiple times to see how the printed number changes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i += 1\n",
    "print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notebooks also allow special blocks to be run. Two special blocks used throughout the ChipWhisperer tutorials are `bash` blocks, which allow bash commands to be run (note: if you're not using a bash-like terminal to run Jupyter, these blocks won't work for you):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "echo \"Test bash\"\n",
    "i=0\n",
    "for j in *; do let \"i=i+1\"; done\n",
    "echo \"there are\" $i \"files/folders in this directory\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And `run` blocks, which run other notebooks:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%run \"Helper_Scripts/Test_Run.ipynb\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code blocks can also be edited by clicking within the code portion of the block (the grey area). You can tell if you're in edit mode by the presence of a green border around the block. If you're not in edit mode, the border will be blue instead."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting with matplotlib"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First off - plotting with matplotlib. This is the easiest to use, as you can plot stuff with `plt.plot()`, and also set a colour as in the following:\n",
    "\n",
    "    import matplotlib.pylab as plt\n",
    "    plt.plot([1,2,2,4,5], 'r')\n",
    "    \n",
    "If you don't see the result, add the following at the end:\n",
    "\n",
    "    plt.show()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pylab as plt\n",
    "plt.plot([1,2,2,4,5], 'r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Often it's nice to have an interactive graph. We can do that with a special *magic* at the start of our notebook, which looks like this:\n",
    "\n",
    "    %matplotlib notebook\n",
    "    import matplotlib.pylab as plt\n",
    "    \n",
    "    plt.plot([1,2,2,4,5], 'r')\n",
    "    plt.plot([3,1,5,5,7], 'g')\n",
    "    \n",
    "Give that a shot right here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "import matplotlib.pylab as plt\n",
    "    \n",
    "plt.plot([1,2,2,4,5], 'r')\n",
    "plt.plot([3,1,5,5,7], 'g')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another feature you'll often want is an ability to run plot commands from inside some loop - for example plotting data in real-time.\n",
    "\n",
    "This can be a little slow - but is a pretty powerful tool. This is easily done by using the interactive plot (previously) in one cell, then doing the update plot in another cell.\n",
    "\n",
    "You'll likely need to add a `fig.canvas.draw()` inside the loop to force the update. The following shows an example of plotting a series of dots (how exciting!) with a delay between each plotting. Note that the figure is generated in the first block, and the actual update happens in the second block."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "import matplotlib.pylab as plt\n",
    "fig = plt.figure()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "for i in range(0, 10):\n",
    "    time.sleep(1)\n",
    "    \n",
    "    ## to update the plot:\n",
    "    plt.plot(-5, i, '.')\n",
    "    fig.canvas.draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Widgets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another super-useful feature is called \"widgets\", which are a way of adding interactive elements to your notebook. They are great for providing status feedback (such as number of traces captured) in a loop.\n",
    "\n",
    "See the [Widget Documentation](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Basics.html) for complete details of all the widgets you might want. You can easily just display the widgets as below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ipywidgets as widgets\n",
    "\n",
    "slider_widget = widgets.FloatSlider( value=0.0,\n",
    "                                     min=0,\n",
    "                                     max=1.0,\n",
    "                                     step=0.01,\n",
    "                                     description=\"Doneness:\",\n",
    "                                     disabled=True,\n",
    "                                     continuous_update=False,\n",
    "                                     orientation='horizontal',\n",
    "                                     readout=True,\n",
    "                                     readout_format='.01f')\n",
    "                                            \n",
    "status_widget = widgets.IntText(     value=0,\n",
    "                                     description=\"Iteration No\",\n",
    "                                     disabled=True)\n",
    "\n",
    "display(slider_widget)\n",
    "display(status_widget)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "for i in range(0, 12):\n",
    "    slider_widget.value = i / 12.0\n",
    "    status_widget.value = i\n",
    "    time.sleep(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Completion Hints"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quick! What does the numpy `np.argmax()` do and what are it's arguments?\n",
    "\n",
    "Luckily we can use some hinting features to tell us this. To try them out:\n",
    "\n",
    "1. Run the block below - because you don't want to continue to the next block, suggest using `Control-Enter` (you'll get an error - we have no argument!)\n",
    "2. Put your cursor inside the `()`, and press `Shift-Tab`. You shold get a pop-up hint window like show here:\n",
    "\n",
    "<img src=\"img/typehint.png\" alt=\"Example Hinting\" width=\"450\"/>\n",
    "\n",
    "Note this works if your cursor is anywhere on the function handle, so you can pretty quickly get this working. The only real requirement is you need to actually run the `import` statement first. Try getting the signature for `np.ndarray` for example by changing to that function first - and again press `Shift-Tab` to get the signature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "np.argmax()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Completing Courses"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ChipWhisperer tutorials that are part of the 'courses' are designed to walk you through various topics. These courses have supplementary material on ChipWhisperer.io that you might enjoy for a deeper dive, but are also designed to work stand-alone to show various features of ChipWhisperer. The tutorials also can be used with other reference books or material on side-channel power analysis and fault injection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "SCOPETYPE = 'OPENADC'\n",
    "PLATFORM = 'CWLITEARM'\n",
    "CRYPTO_TARGET = 'NONE'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are typically used as follows in the tutorial:\n",
    "\n",
    "* `SCOPETYPE` - Indicates the capture hardware to use. If you have a ChipWhisperer Lite or Pro, use `'OPENADC'`. If you have a ChipWhisperer Nano, use `'CWNANO'`.\n",
    "* `PLATFORM` - Selects the target we're attacking. As of ChipWhisperer v5.1.0, tutorials only support at most `'CWLITEARM'` (STM32F3 target), `'CWLITEXMEGA'` (XMEGA target), and `'CWNANO'` (Nano STM32F0 target).\n",
    "* `CRYPTO_TARGET` - Selects the cryptographic library to use on the target. If unsure, use `'AVRCRYPTOLIB'` for the XMEGA target and `'TINYAES128C'` otherwise. Tutorials that don't have this block or use `'NONE'` don't require a crypto library.\n",
    "\n",
    "The parameter blocks should always be the first one run during a tutorial."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## User Folder\n",
    "\n",
    "New in ChipWhisperer 5.7.0 is the `user` folder. This is a special folder that is ignored by git. This means you can make as many changes within that folder without having to worry about colliding with updates. You may find it helpful to copy the folders in `courses` into that folder. If you do so, make sure the relative paths still line up. For example, you should have `user/sca101`, not `user/courses/sca101`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Further Reading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you'd like to learn more about Jupyter Notebooks before diving into the rest of the tutorials, the following links are recommended:\n",
    "\n",
    "* [Jupyter Notebook documentation](https://jupyter-notebook.readthedocs.io/en/stable/)\n",
    "* [A gallery of interesting Jupyter Notebooks](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
